package com.ctjsoft.datacollection.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctjsoft.datacollection.core.povo.Result;
import com.ctjsoft.datacollection.core.repository.RepositoryUtil;
import com.ctjsoft.datacollection.entity.*;
import com.ctjsoft.datacollection.mapper.DiCategoryMapper;
import com.ctjsoft.datacollection.mapper.DiScriptMapper;
import com.ctjsoft.datacollection.mapper.KCategoryMapper;
import com.ctjsoft.datacollection.mapper.KRepositoryMapper;
import com.ctjsoft.datacollection.service.DiScriptService;
import com.ctjsoft.datacollection.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.repository.AbstractRepository;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.trans.TransMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DiScriptServiceImpl  extends ServiceImpl<DiScriptMapper, DiScript> implements DiScriptService {
    @Autowired
    DiCategoryMapper diCategoryMapper;
    @Autowired
    DiScriptMapper diScriptMapper;
    @Autowired
    KRepositoryMapper kRepositoryMapper;
    /**
     *  获取某个目录下的所有子目录Id
     */
    public static void getChildCategoryId(DiCategory d, List<DiCategory> ds, List<String> s) {
        if (Objects.nonNull(ds)) {
            ds.forEach( a -> {
                if (d.getCategoryId().equals(a.getCategoryPid())) {
                    s.add(a.getCategoryId());
                    getChildCategoryId(a, ds, s);
                }
            });
        }
    }
    public Result<DiRespository> add(DiScript diScript) {
        DiRespository dr = new DiRespository();
        try {
            KRepository kRepository=kRepositoryMapper.selectById(diScript.getRepId());
            // 根据目录id查询目录
            DiCategory byId = diCategoryMapper.selectById(diScript.getId());
            // 判断该目录是否存在相同命名的转换
            List<DiScript> scripts = diScriptMapper.findByCategoryIdAndRepId(byId.getCategoryId(), byId.getRepId());
            List<String> collect = scripts.stream().map(DiScript::getName).collect(Collectors.toList());
            if (collect.contains(diScript.getName())) {
                return Result.error("500", "该转换已存在");
            }
            if (diScript.getName() == null || diScript.getName().equals("")) {
                return Result.error("500", "脚本名称不能为空");
            }
            DiScript di = new DiScript();
            if (kRepository!=null) {
                // 连接资源库
                AbstractRepository repository = RepositoryUtil.connection(kRepository);
                if (!repository.isConnected()) {
                    repository.connect(kRepository.getRepUsername(), kRepository.getRepPassword());
                }
                RepositoryDirectoryInterface d = null;
                if (Objects.nonNull(byId)) {
                    d = repository.findDirectory(byId.getPath());
                    di.setPath(byId.getPath() + DiCanstant.FILE_SEPARATOR + diScript.getName());
                    di.setCategoryId(byId.getCategoryId());
                } else {
                    d = repository.findDirectory(DiCanstant.FILE_SEPARATOR);
                    di.setPath(DiCanstant.FILE_SEPARATOR + diScript.getName());
                }
                if (DiCanstant.TRANS.equals(diScript.getType())) {
                    TransMeta a = new TransMeta();
                    a.setRepositoryDirectory(d);
                    a.setName(diScript.getName());
                    repository.save(a, diScript.getName(), null);
                    ObjectId transformationID = repository.getTransformationID(diScript.getName(), d);
                    dr.setTransId(transformationID.getId());
                    di.setScriptId(transformationID.getId());
                    di.setType(DiCanstant.TRANS);
                } else {
                    JobMeta jobMeta = new JobMeta();
                    jobMeta.setRepositoryDirectory(d);
                    jobMeta.setName(diScript.getName());
                    repository.save(jobMeta, diScript.getName(), null);
                    ObjectId jobId = repository.getJobId(diScript.getName(), d);
                    dr.setTransId(jobId.getId());
                    di.setScriptId(jobId.getId());
                    di.setType(DiCanstant.JOB);
                }
            }
            di.setCreateDate(new Date());
            di.setId(StringUtil.uuid());
            di.setName(diScript.getName());
            di.setRepId(diScript.getRepId());
            // 将转换添加进数据库
            diScriptMapper.insert(di);

        } catch (KettleException e) {
            e.printStackTrace();
        }
        return Result.ok(dr);
    }

    public void delete(String id, String type) {
        try {
            DiScript byId = diScriptMapper.selectById(id);
            String repId = byId.getRepId();
            KRepository kRepository=kRepositoryMapper.selectById(repId);
            if (kRepository!=null) {
                // 连接资源库
                AbstractRepository repository = RepositoryUtil.connection(kRepository);
                if (!repository.isConnected()) {
                    repository.connect(kRepository.getRepUsername(), kRepository.getRepPassword());
                }
                RepositoryDirectoryInterface d = null;
                // 判断转换是否在根目录
                if (StringUtils.isEmpty(byId.getCategoryId())) {
                    d = repository.findDirectory(DiCanstant.FILE_SEPARATOR);
                } else {
                    DiCategory categoryDirectoryId = diCategoryMapper.findByCategoryIdAndRepId(byId.getCategoryId(), repId);
                    d = repository.findDirectory(categoryDirectoryId.getPath());
                }
                if (Objects.nonNull(d)) {
                    if (DiCanstant.TRANS.equals(type)) {
                        ObjectId transformationID = repository.getTransformationID(byId.getName(), d);
                        repository.deleteTransformation(transformationID);
                    } else {
                        ObjectId jobId = repository.getJobId(byId.getName(), d);
                        repository.deleteJob(jobId);
                    }

                }
            }
            diScriptMapper.deleteById(byId);
        } catch (KettleException e) {
            e.printStackTrace();
        }
    }
    public void update(DiScript diScript) {
        try {
            DiScript byId = diScriptMapper.selectById(diScript.getId());
            String repId = byId.getRepId();
            KRepository kRepository=kRepositoryMapper.selectById(repId);
            if (kRepository!=null) {
                // 连接资源库
                AbstractRepository repository = RepositoryUtil.connection(kRepository);
                if (!repository.isConnected()) {
                    repository.connect(kRepository.getRepUsername(), kRepository.getRepPassword());
                }
                RepositoryDirectoryInterface d = null;
                ObjectId scriptId = null;
                if (StringUtils.isEmpty(diScript.getCategoryId())) {
                    byId.setPath(DiCanstant.FILE_SEPARATOR + diScript.getName());
                    d = repository.findDirectory(DiCanstant.FILE_SEPARATOR);
                    if (DiCanstant.TRANS.equals(diScript.getType())) {
                        scriptId = repository.getTransformationID(byId.getName(), d);
                    } else {
                        scriptId = repository.getJobId(byId.getName(), d);
                    }
                } else {
                    DiCategory diCategory = diCategoryMapper.findByCategoryIdAndRepId(diScript.getCategoryId(), repId);
                    byId.setPath(diCategory.getPath() + DiCanstant.FILE_SEPARATOR + diScript.getName());
                    d = repository.findDirectory(diCategory.getPath());
                    if (DiCanstant.TRANS.equals(diScript.getType())) {
                        scriptId = repository.getTransformationID(byId.getName(), d);
                    } else {
                        scriptId = repository.getJobId(byId.getName(), d);
                    }
                }
                if (DiCanstant.TRANS.equals(diScript.getType())) {
                    repository.renameTransformation(scriptId, d, diScript.getName());
                } else {
                    repository.renameJob(scriptId, d, diScript.getName());
                }

            }
            byId.setName(diScript.getName());
            // 修改脚本
            diScriptMapper.updateById(byId);
        } catch (KettleException e) {
            e.printStackTrace();
        }
    }
    public Result<List<DiScript>> findDiScriptByCatagoryId(String id, String repId, Integer pageNum, Integer pageSize) {
        DiCategory category = diCategoryMapper.findByCategoryIdAndRepId(id, repId);
        List<DiCategory> all = diCategoryMapper.selectByRepId(repId);
        List<String> s = new ArrayList<>();
        s.add(id);
        // 查找目录下的所有子目录
        getChildCategoryId(category, all, s);
        List<DiScript> scriptList = diScriptMapper.findByCategoryIdInAndRepId(s, repId);
        List<DiScript> collect = scriptList.stream().skip(pageSize * (pageNum - 1)).limit(pageSize).sorted(
                Comparator.comparing(DiScript::getCreateDate)).collect(Collectors.toList());
        return Result.ok(collect, scriptList.size());
    }
    public void moveScript(DiScript di) {
        try {
            DiScript byId = diScriptMapper.selectById(di.getId());
            String repId = byId.getRepId();
            KRepository kRepository=kRepositoryMapper.selectById(repId);
            if (kRepository!=null) {
                // 连接资源库
                AbstractRepository repository = RepositoryUtil.connection(kRepository);
                if (!repository.isConnected()) {
                    repository.connect(kRepository.getRepUsername(), kRepository.getRepPassword());
                }
                // 找到原目录的RepositoryDirectoryInterface
                DiCategory oldCategory = diCategoryMapper.findByCategoryIdAndRepId(byId.getCategoryId(), byId.getRepId());
                RepositoryDirectoryInterface oldDirectory = null;
                if (Objects.nonNull(oldCategory)) {
                    oldDirectory = repository.findDirectory(oldCategory.getPath());
                } else {
                    oldDirectory = repository.findDirectory(DiCanstant.FILE_SEPARATOR);
                }
                ObjectId transformationID = repository.getTransformationID(byId.getName(), oldDirectory);
                // 找到所更新的目录对象
                DiCategory newCategory = diCategoryMapper.selectById( di.getScriptId());
                RepositoryDirectoryInterface d = null;
                if (Objects.nonNull(newCategory)) {
                    d = repository.findDirectory(newCategory.getPath());
                } else {
                    d = repository.findDirectory(DiCanstant.FILE_SEPARATOR);
                }
                repository.renameTransformation(transformationID, d, byId.getName());
                byId.setCategoryId(newCategory.getCategoryId());
                byId.setPath(newCategory.getPath() + DiCanstant.FILE_SEPARATOR + byId.getName());
            }
            byId.setName(byId.getName());
            // 修改脚本
            diScriptMapper.updateById(byId);
        } catch (KettleException e) {
            e.printStackTrace();
        }
    }
    public Map<String, Integer> findTransAndJobById(String id) {
        Map<String, Integer> map = new HashMap<>(8);
        List<DiScript> trans = diScriptMapper.findByRepIdAndType(id, DiCanstant.TRANS);
        List<DiScript> jobs = diScriptMapper.findByRepIdAndType(id, DiCanstant.JOB);
        map.put("trans", trans.size());
        map.put("jobs", jobs.size());
        List<DiCategory> byIsDefault = diCategoryMapper.findByIsDefaultAndRepId(DiCanstant.IS_DEFAULT, id);
        List<DiCategory> all = diCategoryMapper.selectByRepId(id);
        List<String> cjList = new ArrayList<>();
        List<String> aqList = new ArrayList<>();
        List<String> jmList = new ArrayList<>();
        List<String> gxList = new ArrayList<>();
        byIsDefault.forEach(b -> {
            switch (b.getName()) {
                case "数据采集":
                    cjList.add(b.getCategoryId());
                    getChildCategoryId(b, all, cjList);
                    break;
                case "数据安全":
                    aqList.add(b.getCategoryId());
                    getChildCategoryId(b, all, aqList);
                    break;
                case "数据建模":
                    jmList.add(b.getCategoryId());
                    getChildCategoryId(b, all, jmList);
                    break;
                case "数据共享":
                    gxList.add(b.getCategoryId());
                    getChildCategoryId(b, all, gxList);
                    break;
                default:
                    break;
            }
        });
        if (Objects.nonNull(cjList)) {
            map.put("cjtrans", diScriptMapper.findByCategoryIdInAndRepIdAndType(cjList, id, DiCanstant.TRANS).size());
            map.put("cjjobs", diScriptMapper.findByCategoryIdInAndRepIdAndType(cjList, id, DiCanstant.JOB).size());
        } else {
            map.put("cjtrans", 0);
            map.put("cjjobs", 0);
        }
        if (Objects.nonNull(aqList)) {
            map.put("aqtrans", diScriptMapper.findByCategoryIdInAndRepIdAndType(aqList, id, DiCanstant.TRANS).size());
            map.put("aqjobs", diScriptMapper.findByCategoryIdInAndRepIdAndType(aqList, id, DiCanstant.JOB).size());
        } else {
            map.put("aqtrans", 0);
            map.put("aqjobs", 0);
        }
        if (Objects.nonNull(gxList)) {
            map.put("gxtrans", diScriptMapper.findByCategoryIdInAndRepIdAndType(gxList, id, DiCanstant.TRANS).size());
            map.put("gxjobs", diScriptMapper.findByCategoryIdInAndRepIdAndType(gxList, id, DiCanstant.JOB).size());
        } else {
            map.put("gxtrans", 0);
            map.put("gxjobs", 0);
        }
        if (Objects.nonNull(jmList)) {
            map.put("jmtrans", diScriptMapper.findByCategoryIdInAndRepIdAndType(jmList, id, DiCanstant.TRANS).size());
            map.put("jmjobs", diScriptMapper.findByCategoryIdInAndRepIdAndType(jmList, id, DiCanstant.JOB).size());
        } else {
            map.put("jmtrans", 0);
            map.put("jmjobs", 0);
        }
        return map;
    }
}

